// Retoolkit - Scripting-based reverse engineering toolkit for Windows OS'es
// Copyright (C) 2010  James Leskovar
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef GENASSEMBLEREX_H
#define GENASSEMBLEREX_H

#include <string>
#include "AsmJit.h"
#include "GenConfig.h"

namespace GenHook
{
  ////////////////////////////////////
  // AssemblerEx
  ////////////////////////////////////
  class GENHOOK_API AssemblerEx : public AsmJit::Assembler
  {
  public:
    AssemblerEx(void);
    virtual ~AssemblerEx(void);

    // overloaded auxiliary functions
    void  clear();
    
    void* rmake(HANDLE target, void* destination = NULL);
    
    void* make(AsmJit::MemoryManager* memoryManager = NULL, 
               AsmJit::UInt32 allocType = AsmJit::MEMORY_ALLOC_FREEABLE);

    void  setBaseAddress(AsmJit::SysUInt addr);

  protected:
    void embedFarAddr(AsmJit::SysUInt addr);

  private:
    AsmJit::SysUInt m_base;
    void relocCode(void* dst);
  };

  ////////////////////////////////////
  // CopierAsm
  ////////////////////////////////////
  class GENHOOK_API CopierAssembler : public AssemblerEx
  {
  public:
    CopierAssembler(void* baseAddr);
    void consume();
    bool isValid();

    void* getBase();
    void clear();

    std::string getLastInst();

  private:

    std::string m_last;
    void* m_base;
    int m_offset;
    bool m_error;    

  };

} // namespace GenHook

#endif // GENASSEMBLEREX_H
